package com.baiyinet.util;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.icu.math.BigDecimal;
import android.media.ExifInterface;
import android.os.Environment;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;

import com.jude.utils.JUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.UUID;

import id.zelory.compressor.Compressor;
import myandroid.library.util.ApplicationHelper;
import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * @author J.Huang
 * @version 1.0
 * @since 16/11/14
 */

public class Utils {

    public static class UI {
        public static void showToastShort(String text) {
            JUtils.Toast(text);
        }

        public static void showToastLong(String text) {
            JUtils.ToastLong(text);
        }

        public static void closeInputMethod(Activity activity) {
//
            JUtils.closeInputMethod(activity);
        }

        public static void showInputMethod(View view) {
            InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null) {
                view.requestFocus();
                imm.showSoftInput(view, 0);
            }

        }

        public static void hideInputMethod(View view) {
            InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null) {
                imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
            }
        }

        public static int dip2px(float dpValue, Context context) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    }

    public static class Network {
        public static boolean isNetworkAvailable() {
            return JUtils.isNetWorkAvilable();
        }
    }

    public static class App {
        public static String getAppPackageName(Context context) {
            return context.getPackageName();
        }

        public static int getAppVersionCode() {
            return JUtils.getAppVersionCode();
        }

        /**
         * 删除方法
         * @param file
         * */
        private static void deleteFolder(File file) {
            if (!file.exists())
                return;

            if (file.isDirectory()) {
                File files[] = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    deleteFolder(files[i]);
                }
            }
            file.delete();
        }

        /**
         * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache)
         * @param context
         */
        private static void cleanInternalCache(Context context) {
            deleteFolder(context.getCacheDir());
        }

        /** * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context */
        private static void cleanDatabases(Context context) {
            deleteFolder(new File("/data/data/"
                    + context.getPackageName() + "/databases"));
        }

        /**
         * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param
         * context
         */
        private static void cleanSharedPreference(Context context) {
            deleteFolder(new File("/data/data/"
                    + context.getPackageName() + "/shared_prefs"));
        }

        /** * 按名字清除本应用数据库 * * @param context * @param dbName */
        private static void cleanDatabaseByName(Context context, String dbName) {
            context.deleteDatabase(dbName);
        }

        /** * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context */
        private static void cleanFiles(Context context) {
            deleteFolder(context.getFilesDir());
        }

        /**
         * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param
         * context
         */
        private static void cleanExternalCache(Context context) {
            if (Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED)) {
                deleteFolder(context.getExternalCacheDir());
            }
        }

        private static void cleanWebViewCache(Context context) {
            deleteFolder(new File("/data/data/"
                    + context.getPackageName() + "/app_tbs"));
            deleteFolder(new File("/data/data/"
                    + context.getPackageName() + "/app_webview"));
            // 清除cookie即可彻底清除缓存
//            CookieHelper.RemoveCookie(context);
            context.deleteDatabase("webview.db");
            context.deleteDatabase("webviewCache.db");
        }

        /** * 清除自定义路径下的文件，使用需小心，请不要误删。而且只支持目录下的文件删除 * * @param filePath */
        public static void cleanCustomCache(String filePath) {
            deleteFolder(new File(filePath));
        }

        public static void clearCache(Context context) {
//            cleanInternalCache(context);
//            cleanExternalCache(context);
//            cleanDatabases(context);
//            cleanSharedPreference(context);
//            cleanFiles(context);
//            for (String filePath : filepath) {
//                cleanCustomCache(filePath);
//            }
//            cleanWebViewCache(context);
        }
    }

    public static class Image {

        /***
         * 将Bitmap转换成Base64字符串
         * @param src
         * @return
         */
        public static String bitmap2StrByBase64(String src, String format) {
            if (TextUtils.isEmpty(src)) {
                return "";
            }

            int options = 60;
            try {
                FileInputStream fis = new FileInputStream(new File(src));
                double available = fis.available();
                double size = available / 1048576;

                if (size <= 1) {
                    options = 90;
                }else if (size > 1 && size <= 2) {
                    options = 80;
                }else if (size > 2 && size <= 4) {
                    options = 50;
                }else if (size > 4 && size <= 5) {
                    options = 35;
                }else if (size > 5 && size <= 6) {
                    options = 25;
                }else if (size > 6 && size <= 7) {
                    options = 15;
                }else if (size > 7 && size <= 8) {
                    options = 10;
                }else if (size > 8 && size <= 9) {
                    options = 7;
                }else if (size > 9) {
                    options = 4;
                }

                fis.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            Bitmap bitmap = BitmapFactory.decodeFile(src);

            int degree = getPhotoDegree(src);
            if (degree != 0) {
                bitmap = rotateBitmap(bitmap, degree);
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);

            if (baos.toByteArray().length > 499 * 1024) {
                if (options < 10) {
                    options -= 2;
                }else {
                    options -= 5;
                }
                baos.reset();
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
            }

            byte[] bytes = baos.toByteArray();

            try {
                baos.flush();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return Base64.encodeToString(bytes, Base64.DEFAULT);
        }

        public static String getBase64(String srcPath,Context context){
            try {
                File tempFile = new File(srcPath);

                BitmapFactory.Options newOpts = new BitmapFactory.Options();
                //开始读入图片，此时把options.inJustDecodeBounds 设回true了
                newOpts.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(srcPath, newOpts);
                float size = computeSize(newOpts.outWidth, newOpts.outHeight);
                float outHeight = newOpts.outHeight / size;
                float outWidth = newOpts.outWidth / size;
                // 获取图片参数
                File compressedImage = new Compressor(context)
                        .setMaxWidth((int) outHeight)
                        .setMaxHeight((int) outWidth)
                        .setQuality(40)
                        .setCompressFormat(Bitmap.CompressFormat.JPEG)
                        .compressToFile(tempFile);
                FileInputStream fis = new FileInputStream(compressedImage);
                byte[] bytes = new byte[fis.available()];
                fis.read(bytes);
                fis.close();

                compressedImage.delete();

                return Base64.encodeToString(bytes, Base64.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }

            return "";
        }

        private static String fileToBase64(FileInputStream is) throws IOException {
            byte[] bytes = new byte[is.available()];

            is.read(bytes);
            is.close();

            return Base64.encodeToString(bytes, Base64.DEFAULT);
        }


        public static String getBase64(String srcPath) {

            File tempFile = new File(srcPath);

            int option = 60;

            try {
                FileInputStream is = new FileInputStream(tempFile);
                int size = is.available()/ 1024;

                if (size <= 500) {
                    return fileToBase64(is);
                }else if (size > 500 && size < 1024) {
                    option = 80;
                }

                BitmapFactory.Options newOpts = new BitmapFactory.Options();
                newOpts.inJustDecodeBounds = true;
                // 获取图片参数
                BitmapFactory.decodeFile(srcPath,newOpts);

//            float outHeight = newOpts.outHeight / computeSize(newOpts.outWidth,newOpts.outHeight);
//            float outWidth = newOpts.outWidth / computeSize(newOpts.outWidth,newOpts.outHeight);
//            newOpts.outHeight = (int) outHeight;
//            newOpts.outWidth = (int) outWidth;
                newOpts.inSampleSize = getComputeSize(newOpts.outWidth,newOpts.outHeight);

                //  重新读入图片
                newOpts.inJustDecodeBounds = false;
                Bitmap bitmap = BitmapFactory.decodeStream(is,null, newOpts);

                int degree = getPhotoDegree(srcPath);
                if (degree != 0) {
                    bitmap = rotateBitmap(bitmap, degree);
                }

                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                bitmap.compress(Bitmap.CompressFormat.JPEG, option, baos);

                byte[] bytes = baos.toByteArray();

                baos.flush();
                baos.close();
                is.close();

                return Base64.encodeToString(bytes, Base64.DEFAULT);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return "";
        }

        /***
         * 图片的缩放方法
         *
         * @param bitmap   ：源图片资源
         * @param newWidth  ：缩放后宽度
         * @param newHeight ：缩放后高度
         * @return
         */
        public static Bitmap zoomImage(Bitmap bitmap, float newWidth,
                                       float newHeight) {
            // 获取这个图片的宽和高
            float width = bitmap.getWidth();
            float height = bitmap.getHeight();
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            // 计算宽高缩放率
            float scaleWidth = newWidth / width;
            float scaleHeight = newHeight / height;
            // 缩放图片动作
            matrix.postScale(scaleWidth, scaleHeight);
            return Bitmap.createBitmap(bitmap, 0, 0, (int) width,
                    (int) height, matrix, true);
        }

        public static byte[] bitmap2Bytes(Bitmap bitmap, boolean paramBoolean) {
            Bitmap localBitmap = Bitmap.createBitmap(120, 120, Bitmap.Config.ARGB_8888);
            Canvas localCanvas = new Canvas(localBitmap);
            int i;
            int j;
            if (bitmap.getHeight() > bitmap.getWidth()) {
                i = bitmap.getWidth();
                j = bitmap.getWidth();
            } else {
                i = bitmap.getHeight();
                j = bitmap.getHeight();
            }
            while (true) {
                localCanvas.drawBitmap(bitmap, new Rect(0, 0, i, j), new Rect(0, 0, 120, 120), null);
                if (paramBoolean)
                    bitmap.recycle();
                ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
                localBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
                        localByteArrayOutputStream);
                localBitmap.recycle();
                byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();
                try {
                    localByteArrayOutputStream.close();
                    return arrayOfByte;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                i = bitmap.getHeight();
                j = bitmap.getHeight();
            }
        }

        public static byte[] getImageBytesFromUrl(String strUrl) throws IOException {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");   //设置请求方法为GET
            conn.setReadTimeout(5 * 1000);    //设置请求过时时间为5秒
            InputStream inputStream = conn.getInputStream();   //通过输入流获得图片数据
            return getBytesFromInputStream(inputStream);     //获得图片的二进制数据
        }

        /***
         * 判断照片角度
         *
         * @param path
         * @return
         */
        public static int getPhotoDegree(String path) {
            int degree = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(path);
                int orientation = exifInterface.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return degree;
        }

        /***
         * 旋转照片
         *
         * @param bitmap
         * @param degree
         * @return
         */
        public static Bitmap rotateBitmap(Bitmap bitmap, int degree) {
            if (bitmap != null) {
                Matrix m = new Matrix();
                m.postRotate(degree);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                        bitmap.getHeight(), m, true);
                return bitmap;
            }
            return null;
        }
    }

    public static class MultiPart {
        public static final String MULTIPART_FORM_DATA = "multipart/form-data";

        public static void putRequestBodyMap(Map<String, RequestBody> map, String key, String value) {
            putRequestBodyMap(map, key, createPartFromString(value));
        }

        @NonNull
        static RequestBody createPartFromString(String descriptionString) {
            if (descriptionString == null) {
                descriptionString = "";
            }
            return RequestBody.create(
                    MediaType.parse(MULTIPART_FORM_DATA), descriptionString);
        }

        static void putRequestBodyMap(Map<String, RequestBody> map, String key, RequestBody body) {
            if (!TextUtils.isEmpty(key) && body != null) {
                map.put(key, body);
            }
        }
    }

    public static String getFileExtensionFromUrl(String url) {
        if (!TextUtils.isEmpty(url)) {
            int fragment = url.lastIndexOf("#");
            if (fragment > 0) {
                url = url.substring(0, fragment);
            }

            int query = url.lastIndexOf("?");
            if (query > 0) {
                url = url.substring(0, query);
            }

            int filenamePos = url.lastIndexOf(File.separator);
            String filename =
                    0 <= filenamePos ? url.substring(filenamePos + 1) : url;

            // if the filename contains special characters, we don't
            // consider it valid for our matching purposes:
            if (!filename.isEmpty()) {
                int dotPos = filename.lastIndexOf(".");
                if (0 <= dotPos) {
                    return filename.substring(dotPos + 1);
                }
            }
        }

        return "";
    }

    /***
     * 从数据流中获得数据
     */
    public static byte[] getBytesFromInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 根据图片尺寸确定缩放比例
     *
     * @param srcWidth
     * @param srcHeight
     * @return
     */
    private static int getComputeSize(int srcWidth, int srcHeight) {
        int width = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
        int height = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;

        int longSide = Math.max(width, height);
        int shortSide = Math.min(width, height);

        float scale = ((float) shortSide / longSide);
        if (scale <= 1 && scale > 0.5625) {
            if (longSide < 1664) {
                return 1;
            } else if (longSide >= 1664 && longSide < 4990) {
                return 2;
            } else if (longSide > 4990 && longSide < 10240) {
                return 4;
            } else {
                return longSide / 1280 == 0 ? 1 : longSide / 1280;
            }
        } else if (scale <= 0.5625 && scale > 0.5) {
            return longSide / 1280 == 0 ? 1 : longSide / 1280;
        } else {
            return (int) Math.ceil(longSide / (1280.0 / scale));
        }
    }

    private static float computeSize(int srcWidth,int srcHeight) {
        float sampleSize;

        int width = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
        int height = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;

        int longSide = Math.max(width, height);
        int shortSide = Math.min(width, height);

        float scale = ((float) shortSide / longSide);
        if (scale <= 1 && scale > 0.5625) {
            if (longSide < 1664) {
                sampleSize = 1;
            } else if (longSide >= 1664 && longSide < 4990) {
                sampleSize = 1.5f;
            } else if (longSide > 4990 && longSide < 10240) {
                sampleSize = 4;
            } else {
                sampleSize = longSide / 1280 == 0 ? 1 : longSide / 1280;
            }
        } else if (scale <= 0.5625 && scale > 0.5) {
            sampleSize = longSide / 1280 == 0 ? 1 : longSide / 1280;
        } else {
            sampleSize = (int) Math.ceil(longSide / (1280.0 / scale));
        }

        return sampleSize;
    }



    private static long lastClickingTime;

    public static boolean isFastDoubleClicking() {
        long time = SystemClock.elapsedRealtime();
        long timeDiff = time - lastClickingTime;
        if (timeDiff > 0 && timeDiff < 800) {
            return true;
        }
        lastClickingTime = time;
        return false;
    }

    private static long lastLoadingTime;

    public static boolean isFastLoading() {
        long time = SystemClock.elapsedRealtime();
        long timeDiff = time - lastLoadingTime;
        if (timeDiff > 0 && timeDiff < 1500) {
            return true;
        }
        lastLoadingTime = time;
        return false;
    }

    public static String getDeviceUniqueID(Context context) {
        final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        final String tmDevice, tmSerial, androidId;
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            return "";
        }
        tmDevice = "" + tm.getDeviceId();
        tmSerial = "" + tm.getSimSerialNumber();
        androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

        UUID deviceUuid = new UUID(androidId.hashCode(),
                ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
        return deviceUuid.toString();
    }

    public static void webViewBackAction(Activity activity, WebView webView) {
        if (webView.canGoBack()) {
        // 返回webView的上一页面
            webView.goBack();
        } else {
            ApplicationHelper.getInstance().removeActivity(activity);
        }
    }
}
